home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / tpref.exe / TPR3C.TXT < prev    next >
Text File  |  1992-10-19  |  61KB  |  1,498 lines

  1.                    Chapter 3
  2.                  - continued -
  3.                  - Part 3 of 3 parts -
  4.                                     of the
  5.                             Turbo Pascal Reference
  6.  
  7.                            The Turbo Pascal Language
  8.  
  9.  
  10. This chapter is part of the Turbo Pascal Reference electronic freeware book (C)
  11. Copyright 1992 by Ed Mitchell.  This freeware book contains supplementary
  12. material to Borland Pascal Developer's Guide, published by Que Corporation,
  13. 1992.  However, Que Corporation has no affiliation with nor responsibility for
  14. the content of this free book.  Please see Chapter 1 of the Turbo Pascal
  15. Reference for important information about your right to distribute and use this
  16. material freely.  If you find this material of use, I would appreciate your
  17. purchase of one my books, such as the Borland Pascal Developer's Guide or
  18. Secrets of the Borland C++ Masters, Sams Books, 1992.  Thank you.
  19.  
  20. Functions
  21. Syntax:
  22.  
  23.      function <identifier> <parameter list> : <data type>
  24.  
  25. Examples:
  26.  
  27.      function Minimum ( A, B : Integer ) : Integer;
  28.      { Returns the value of the smaller number A, or B }
  29.      begin
  30.        if A < B then
  31.           Minimum := A
  32.        else { if B < A or B = A then }
  33.           Minimum := B;
  34.      end;
  35.  
  36.      { Example of a function returning a String value }
  37.      function LowerCase (S : String ) : String;
  38.      { Convert string S to lower case, returning the result }
  39.  
  40.      var
  41.        I : Integer;
  42.      begin
  43.        for I := 1 to length(S)  do
  44.           if ((S[I]>='A') and (S[I]<='Z'))  then
  45.             S[I] :=  Chr( Ord( S[I] ) + 32 );
  46.        LowerCase := S;
  47.      end; { LowerCase }
  48.  
  49. Description:
  50.      A function is similar to a procedure, except that a function is called
  51. from within an expression and it returns a value that is then used in
  52. evaluating the overall expression.  Functions can have both value and variable
  53. parameters, and may be declared as near, far, forward, and external, or may be
  54. implemented entirely in assembly language.  Functions may not, however, be
  55. declared as interrupt functions.
  56.  
  57.  
  58. Calling a function
  59.      The function is called by appearing within an expression, such as,
  60.  
  61.      I := Min ( X1, X2 ) + 1;
  62.  
  63.  
  64. Assigning a value to a function identifier
  65.      The function's block definition must include a statement that assigns a
  66. value to the function's identifier.  This is how a function gets a value that
  67. it can return to the caller.  If you omit this assignment statement, or the
  68. assignment statement does not get executed as a result of conditional
  69. statements in the function's code, then the function returns an undefined or
  70. potentially random value.  If during the course of debugging a program you find
  71. your functions returning erratic values, be certain that the function
  72. identifier is  correctly assigned a value.
  73.      Examples of assigning values to function identifiers appear above in the
  74. Min and LowerCase functions.
  75.  
  76.  
  77. Acceptable Function Return Values
  78.      The data type that a function returns can be any of the following:
  79.  
  80.        Any ordinal value, including Boolean, Byte, Char, Smallint, Integer,
  81.        Word, Longint, and enumarated data types and user defined sub range
  82.        types.
  83.  
  84.        Real, Single, Double, Extended and Comp data types,
  85.  
  86.        Pointer values
  87.  
  88.        Strings.
  89.  
  90.  
  91. Functions may not return records or sets, although they may return pointers to
  92. records or sets.
  93.  
  94.  
  95. Recursive functions
  96.      Functions may call themselves.  Such a function is called a recursive
  97. function.  A popular and simple example of a recursive function is a function
  98. that computes the factorial of a number.  The factorial of a number n, is n *
  99. (n-1) * (n-2) ... until n reaches 1.  For example, the factorial of 5, is 5 * 4
  100. * 3 * 2 * 1, which equals 120.  An illustration of how this might be solved
  101. recursively is shown in listing 3.10.  (Actually, its not necessary to use a
  102. recursive function to compute a factorial;  this method is used here for
  103. illustration only.)
  104.  
  105. Listing 3.10.  An example of a recursive function.
  106.    1  program DemoRecursion; {DEMORECU.PAS}
  107.    2  
  108.    3  function Factorial ( n : real ) : real;
  109.    4  begin
  110.    5    if n = 1 then
  111.    6      Factorial := 1
  112.    7    else
  113.    8      Factorial := N * Factorial ( N - 1.0 );
  114.    9  end;
  115.   10  
  116.   11  var
  117.   12    X : Real;
  118.   13  
  119.   14  begin
  120.   15    Write('Enter a number:  ');
  121.   16    Readln( X );
  122.   17    Writeln;
  123.   18    Writeln('Factorial of ',X,' = ', Factorial ( X ) );
  124.   19    Writeln;
  125.   20    Write('Press Enter to finish.');
  126.   21    Readln;
  127.   22  end.
  128.   23  
  129.  
  130. Important note:  The effect of short-circuit evaluation on functions
  131.      By default, Turbo Pascal generates short-circuit evaluation code, so it is
  132. possible that a function may not be called within a particular expression.  For
  133. example, consider a function defined as:
  134.  
  135.      function ValueInRange ( X1 : Integer ) : Boolean;
  136.      begin
  137.        ...
  138.        if  X1 > 0  then
  139.           ValueInRange := True
  140.        else
  141.           ValueInRange := False;
  142.        if  X1 < LowestCoordinate  then
  143.           LowestCoordinate := X1;
  144.      end;
  145.  
  146. In this function, a global variable LowestCoordinate may have its value changed
  147. during the course of execution.  If this function is called in an expression
  148. such as,
  149.  
  150.      if (X1<>X2) and ValueInRange(X1)  then ...
  151.  
  152. In normal short-circuit evaluation, if X1 is not equal to X2, then the
  153. remainder of the expression will not be evaluated.  If your code depends upon
  154. the value of LowestCoordinate being set as a side effect of the ValueInRange
  155. function call, this may result in an error.  In general, it is best to avoid
  156. side-effects within functions and procedures, but if you must make use of
  157. side-effect such as this, you should disable short-circuit evaluation to force
  158. the entire expression to be fully evaluated.  See the section "Compiler
  159. Directives" for more information on using the {$B+} option to enable full
  160. expression evaluation.
  161.  
  162.  
  163. Procedures and Functions as Parameters
  164.      A procedure or function may itself be passed to another procedure or
  165. function as a parameter value.  To pass a procedure or function as a parameter
  166. requires that a type declaration define a procedure type that matches the
  167. appropriate procedure or function header.  This type becomes the parameter type
  168. used in the procedure parameter list.  Listng 3.11 demonstrates the use of a
  169. procedure parameter.
  170.      Note that the type declaration describes the procedure or function that is
  171. called, and does not include the actual procedure or function identifier.
  172.  
  173. Listing 3.11.  Using a procedure type as a procedure parameter.
  174.    1  Program ProcParameter;{PROCPARM.PAS}
  175.    2  { Demonstrates using a procedure type as a procedure
  176.        parameter }
  177.    3  
  178.    4  type
  179.    5    FormatProc = procedure ( X : Integer );
  180.    6  
  181.    7  
  182.    8  const
  183.    9    MaxListSize = 15;
  184.   10    Values: array[1..MaxListSize] of Integer =
  185.   11       (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
  186.   12  
  187.   13  
  188.   14  
  189.   15  function Hexadecimal ( X: Word ) : String;
  190.   16  var
  191.   17    HiByte, LoByte : Word;
  192.   18  
  193.   19    function HexConvert( B : Byte ) : String;
  194.   20    const
  195.   21      HexTable : Array[0..15] of Char =
  196.   22        ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  197.   23         'A', 'B', 'C', 'D', 'E', 'F');
  198.   24    begin
  199.   25      HexConvert := HexTable[B div 16] + HexTable[B and 15];
  200.   26    end;
  201.   27  
  202.   28  begin
  203.   29    HiByte := X Div 256;
  204.   30    LoByte := X and 255;
  205.   31    Hexadecimal := HexConvert( HiByte ) + HexConvert(LoByte);
  206.   32  end;
  207.   33  
  208.   34  
  209.   35  
  210.   36  procedure PrintInteger( X : Integer ); far;
  211.   37  begin
  212.   38  
  213.   39    Writeln( X : 5 );
  214.   40  
  215.   41  end;
  216.   42  
  217.   43  
  218.   44  
  219.   45  procedure PrintHex( X : Integer ); far;
  220.   46  begin
  221.   47  
  222.   48    Writeln ( Hexadecimal ( X ) );
  223.   49  
  224.   50  
  225.   51  end;
  226.   52  
  227.   53  
  228.   54  procedure PrintPercent( X : Integer ); far;
  229.   55  begin
  230.   56  
  231.   57    Writeln( X, '%');
  232.   58  
  233.   59  end;
  234.   60  
  235.   61  
  236.   62  procedure Traverse ( Proc : FormatProc );
  237.   63  var
  238.   64